package com.itheima.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itheima.autoconfig.template.OssTemplate;
import com.itheima.commons.utils.Constants;
import com.itheima.dubbo.api.UserInfoApi;
import com.itheima.dubbo.api.VideoApi;
import com.itheima.model.domain.UserInfo;
import com.itheima.model.enums.CommentType;
import com.itheima.model.enums.VideoType;
import com.itheima.model.mongo.Comment;
import com.itheima.model.mongo.FocusUser;
import com.itheima.model.mongo.Video;
import com.itheima.model.vo.ErrorResult;
import com.itheima.model.vo.PageResult;
import com.itheima.model.vo.VideoVo;
import com.itheima.server.exception.BusinessException;
import com.itheima.server.interceptor.UserHolder;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class SmallVideoService {
    @Autowired
    private FastFileStorageClient client;
    @Autowired
    private FdfsWebServer webServer;
    @DubboReference
    private VideoApi videoApi;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @DubboReference
    private UserInfoApi userInfoApi;
    /*
    视频封面文件
    视频文件*/
    public void upload(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {
        if (videoThumbnail.isEmpty() || videoFile.isEmpty()) {
            throw new BusinessException(ErrorResult.error());
        }
        //将视频文件上传到fastDFS并获取url
        String fileName = videoFile.getOriginalFilename().substring(videoFile.getOriginalFilename().lastIndexOf(".") + 1);
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), fileName, null);
        String videoUrl = webServer.getWebServerUrl() + storePath.getFullPath();
        //将视频封面文件上传到aliyun oss 并返回url
        String imageUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());
        //封装videos对象并保存。
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(imageUrl);
        video.setVideoUrl(videoUrl);
        video.setText("哈哈哈");
        String videoId = videoApi.save(video);
        if (StringUtils.isEmpty(videoId)) {
            throw new BusinessException(ErrorResult.error());
        }
    }
    /*查看视频列表*/
    @Cacheable(value = "videos",
            key="T(com.itheima.server.interceptor.UserHolder).getUserId()+'_'+#page+'_'+#pagesize")//userid_page_pagesize
    public PageResult pageList(Integer page, Integer pagesize) {

        //先从redis中获取推荐数据(vids)
        String key = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId()+100;//不想看推荐的数据
        String value = redisTemplate.opsForValue().get(key);
        List<Video> video = Collections.EMPTY_LIST;//创建一个空的数组
        List<VideoVo> vos =new ArrayList<>();//创建一个空的数组
        //判断数据是否存在
        int valuePageSize = 0;
        if (!StringUtils.isEmpty(value)) {
            //如果redis数据存在，根据vid查询数据
            String[] values = value.split(",");
            if ((page - 1) * pagesize < values.length) {
                List<Long> vids = Arrays.stream(values).skip((page - 1) * pagesize).limit(pagesize).map(it -> Long.valueOf(it)).collect(Collectors.toList());
                //调用api根据pid数据查询动态数据
                video = videoApi.finByVids(vids);
            }
            valuePageSize = PageUtil.totalPage(values.length, pagesize);
        }
        if (video.isEmpty()) {
            //查询的数据是空的就随机获取数据
            video = videoApi.findRandom(page - valuePageSize, pagesize);
        }
        //提取视频列表中所有的用户id
        List<Long> userId = CollUtil.getFieldValues(video, "userId", Long.class);
        //查询用户信息
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userId, null);
        for (Video video1 : video) {
            vos.add(VideoVo.init(userInfoMap.get(video1.getUserId()),video1));
        }
        //构建返回值
        return new PageResult(page,pagesize, (long) vos.size(),vos);
    }
    /*关注*/
    public void userFocus(Long followUserId) {
        Boolean res=  videoApi.hasVideo(followUserId,UserHolder.getUserId(), VideoType.LOVE);
        if(res){
            throw  new BusinessException(ErrorResult.error());
        }
        FocusUser focusUser =new FocusUser();
        focusUser.setUserId(UserHolder.getUserId());
        focusUser.setFollowUserId(followUserId);;
        videoApi.saveFocusUser(focusUser);
        //记录到redis中
        String key = Constants.FOCUS_USER + UserHolder.getUserId();
        String hashKey = String.valueOf(focusUser);
        redisTemplate.opsForHash().put(key,hashKey,"1");

    }
    /*取消关注*/
    public void userUnFocus(Long followUserId) {
        //判断
        Boolean res=  videoApi.hasVideo(followUserId,UserHolder.getUserId(), VideoType.LOVE);
        if(res){
            throw  new BusinessException(ErrorResult.error());
        }
        //调用api删除数据

        videoApi.delete(UserHolder.getUserId(),followUserId);

        String key = Constants.FOCUS_USER + UserHolder.getUserId();
        String hashKey = String.valueOf(followUserId);
        redisTemplate.opsForHash().delete(key,hashKey);
    }


    //取消点赞
    public void  dislike(String id) {
        Boolean res = videoApi.hasLike(id,UserHolder.getUserId(),VideoType.LIKE);
        if(res){
            throw new BusinessException(ErrorResult.likeError());
        }
        videoApi.deteleById(id);
    }
    //点赞
    public void like(String id) {
        Boolean res = videoApi.hasLike(id,UserHolder.getUserId(),VideoType.LIKE);
        if(res){
            throw new BusinessException(ErrorResult.likeError());
        }
        videoApi.updateById(id);
    }

    public void saveComments(String id, String comment) {
        Comment comment1 = new Comment();
        comment1.setPublishId(new ObjectId(id));//将String类型的movementId自动转换为ObjectId类型
        comment1.setCommentType(CommentType.COMMENT.getType());//通过枚举获取是评论还是点赞还是收藏
        comment1.setContent(comment);
        comment1.setUserId(UserHolder.getUserId());

        videoApi.saveComment(comment1);//保存评论，并返回该动态的评论总数
    }
}
